﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using DevToolkit.CustomClasses;

namespace DevToolkit
{
    public partial class Form1 : Form
    {
        ////////////////////////////////////////////////////////////////////////////////////////////////
        //  Data members                                                   
        ////////////////////////////////////////////////////////////////////////////////////////////////
        DriveInfo[] drives = null;
        bool packageIntegrity = false;
        string removableDriveLetter = string.Empty;
        string packageLocation = string.Empty;
        RequiredInfo info;

        public Form1()
        {
            InitializeComponent();

            drives = DriveInfo.GetDrives();
            foreach( DriveInfo drive in drives )
            {
                if( drive.IsReady && drive.DriveType == DriveType.Removable )
                {
                    removableDriveLetter = drive.Name;

                    if( Directory.Exists( removableDriveLetter + "PortableApps/PortableApps.com" ))
                    {
                        if (File.Exists(removableDriveLetter + "PortableApps/PortableApps.com/PortableAppsPlatform.exe") &&
                            File.Exists(removableDriveLetter + "PortableApps/PortableApps.com/PortableAppsUpdater.exe") &&
                            File.Exists(removableDriveLetter + "PortableApps/PortableApps.com/PortableAppsBackup.exe") &&
                            File.Exists(removableDriveLetter + "PortableApps/PortableApps.com/PortableAppsBackupRestore.exe"))
                        {
                            PackageLocationTextBox.Text = removableDriveLetter;
                        }
                    }
                }
            }

            info = new RequiredInfo(null);
        }

        #region Status Updating Function
        private void ValidationButton_MouseEnter(object sender, EventArgs e)
        {
            statusLabel.Text = "Validates the application compliance to PortableApps.com Format Specifications 3.0";
        }
        
        private void EditSettingsButton_MouseEnter(object sender, EventArgs e)
        {
            statusLabel.Text = "Configure the applications settings in appinfo.ini";            
        }

        private void StatusLabel_Reset(object sender, EventArgs e)
        {
            statusLabel.Text = string.Empty;
        }

        private void CreateInstallerButton_MouseEnter(object sender, EventArgs e)
        {
            statusLabel.Text = "Generates a PortableApps.com Installer";
        }

        private void NewApplicationButton_MouseEnter(object sender, EventArgs e)
        {
            statusLabel.Text = "Generates an PortableApps.com application directory and required files";
        }

        private void BrowseButton_MouseEnter(object sender, EventArgs e)
        {
            statusLabel.Text = "Search for an applications base directory";
        }
        #endregion


        #region Browse Button Functions
        private void BrowseButton_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog folderDiag = new FolderBrowserDialog();
            if (folderDiag.ShowDialog() == DialogResult.OK)
            {
                packageLocation = folderDiag.SelectedPath;

                // Check the integrity of the files
                if (CheckPackageIntegrity() == false)
                {
                    MessageBox.Show("Package did not pass the integrity check!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    packageLocation = string.Empty;
                    return;
                }


                PackageLocationTextBox.Text = packageLocation;
            }
            EditSettingsButton.Enabled = true;
        } 
        #endregion


        #region Edit Settings Function
        private void EditSettingsButton_Click(object sender, EventArgs e)
        {
            EditWindow settingsWindow = new EditWindow(packageLocation, removableDriveLetter);
            
            // load the information from the file
            LoadRequiredInfo();
            settingsWindow.Info = info;

            // Save the data from the fixed window into the appinfo.ini file
            if (DialogResult.OK == settingsWindow.ShowDialog())
            {
                // Copy the info over from the other form
                info = settingsWindow.Info;
                                
                ValidationButton.Enabled = true;
            }
        } 
        #endregion


        #region Installer Button Functions
        private void CreateInstallerButton_Click(object sender, EventArgs e)
        {
            if (File.Exists(removableDriveLetter + "PortableApps/PortableApps.comLauncher/PortableApps.comLauncherGenerator.exe") == false)
                MessageBox.Show("Cannot find PortableApps.com Launcher Generator!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            else if (File.Exists(removableDriveLetter + "PortableApps/PortableApps.comInstaller/PortableApps.comInstaller.exe") == false)
                MessageBox.Show("Cannot find PortableApps.com Installer Generator!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            else
            {
                this.Visible = false;
                {
                    // Creates the launcher for the application
                    Process launcher = new Process();
                    launcher.StartInfo.FileName = removableDriveLetter + "PortableApps/PortableApps.comLauncher/PortableApps.comLauncherGenerator.exe";
                    launcher.StartInfo.Arguments = packageLocation;
                    launcher.Start();
                    launcher.WaitForExit();

                    // Creates a new process for the installer program to launch
                    Process install = new Process();

                    // Sets the filename to tell the process which executable to launch
                    install.StartInfo.FileName = removableDriveLetter + "PortableApps/PortableApps.comInstaller/PortableApps.comInstaller.exe";

                    // Sends the command line arguments to the installer being launched
                    // which will be the location to the package specified
                    install.StartInfo.Arguments = packageLocation;

                    // Starts the process which is the PA.c installer
                    install.Start();

                    // Does what it says, will wait until the installer has closed
                    install.WaitForExit();
                }
                this.Visible = true;
            }
        } 
        #endregion


        #region New Application Button Functions
        private void NewApplicationButton_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog folderBrowser = new FolderBrowserDialog();

            if (DialogResult.OK == folderBrowser.ShowDialog())
            {
                packageLocation = folderBrowser.SelectedPath;

                if (Directory.EnumerateFileSystemEntries(packageLocation).Any())
                {
                    MessageBox.Show("Selected directory is not empty!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                string sourceDirectory = @"../DevToolkitPortable/App/DefaultData/template";

                // copy a directory
                foreach (string dirPath in Directory.GetDirectories(sourceDirectory, "*", SearchOption.AllDirectories))
                    Directory.CreateDirectory(dirPath.Replace(sourceDirectory, packageLocation));

                //Copy all the files
                foreach (string newPath in Directory.GetFiles(sourceDirectory, "*.*", SearchOption.AllDirectories))
                    File.Copy(newPath, newPath.Replace(sourceDirectory, packageLocation));
            
                PackageLocationTextBox.Text = packageLocation;
                EditSettingsButton.Enabled = true;
            }
        } 
        #endregion


        #region Checking Package Integrity
        private bool CheckPackageIntegrity(object sender = null)
        {
            // Opened for reading
            if (packageLocation != string.Empty)
            {
                // Create a inifile object sending the package location to open up
                IniFile file = new IniFile(packageLocation + "\\App\\AppInfo\\appinfo.ini");
                List<bool> integrity = new List<bool>();

                //========================================================
                // Checking the   [Format] section
                //========================================================
                integrity.Add(file.KeyExists("Type", "Format"));
                integrity.Add(file.KeyExists("Version", "Format"));

                //========================================================
                // Checking the   [Details] section
                //========================================================
                integrity.Add(file.KeyExists("Name", "Details"));
                integrity.Add(file.KeyExists("AppID", "Details"));
                integrity.Add(file.KeyExists("Publisher", "Details"));
                integrity.Add(file.KeyExists("Homepage", "Details"));
                integrity.Add(file.KeyExists("Category", "Details"));
                integrity.Add(file.KeyExists("Description", "Details"));
                integrity.Add(file.KeyExists("Language", "Details"));

                //========================================================
                // Checking the   [License] section
                //========================================================
                integrity.Add(file.KeyExists("Shareable", "License"));
                integrity.Add(file.KeyExists("OpenSource", "License"));
                integrity.Add(file.KeyExists("Freeware", "License"));
                integrity.Add(file.KeyExists("CommercialUse", "License"));

                //========================================================
                // Checking the   [Version] and [SpecialPaths] section
                //========================================================
                integrity.Add(file.KeyExists("PackageVersion", "Version"));
                integrity.Add(file.KeyExists("DisplayVersion", "Version"));
                
                //========================================================
                // Checking the   [Control] section
                //========================================================
                integrity.Add(file.KeyExists("Icons", "Control"));
                integrity.Add(file.KeyExists("Start", "Control"));

                // Now finally go through and check all of the bools
                foreach (bool temp in integrity)
                {
                    if (temp == false)
                        return false;
                }

                if (packageIntegrity == false)
                    packageIntegrity = true;
                return true;
            }

            // Filepath not valid
            return false;           
        }
        #endregion


        #region Validation Button Functions
        private void ValidationButton_Click(object sender, EventArgs e)
        {
            Validation validate = new Validation( packageLocation, removableDriveLetter );
            validate.Info = info;
            if (validate.ShowDialog() == DialogResult.OK)
            {
                bool temp = validate.ValidationPassed;

                if (temp == true)
                    CreateInstallerButton.Enabled = true;
            }

            //IniFile file = new IniFile(packageLocation + "\\App\\AppInfo\\appinfo.ini");
            //
            //List<bool> list = new List<bool>();
            //list.Add(file.SectionExists("Format"));
            //list.Add(file.SectionExists("Control"));
            //
            //foreach (bool sec in list)
            //{
            //    if (sec == false)
            //    {
            //        MessageBox.Show("Validation Failed!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            //        return;
            //    }
            //}
        } 
        #endregion


        #region Load RequiredInfo Function
        private void LoadRequiredInfo()
        {
            IniFile file = new IniFile(packageLocation + "/App/AppInfo/appinfo.ini");

            if( file.KeyExists("Name", "Details"))
                info.appname = file.ReadValue("Name", "Details");
            
            if( file.KeyExists("AppID", "Details"))
                info.appid = file.ReadValue("AppID", "Details");
            
            if( file.KeyExists("Publisher", "Details"))
                info.publisher = file.ReadValue("Publisher", "Details");
            
            if( file.KeyExists("Homepage", "Details"))
                info.homepage = file.ReadValue("Homepage", "Details");
            
            if( file.KeyExists("Category", "Details"))
                info.category = file.ReadValue("Category", "Details");
            
            if( file.KeyExists("Description", "Details"))
                info.description = file.ReadValue("Description", "Details");
            
            if( file.KeyExists("Language", "Details"))
                info.language = file.ReadValue("Language", "Details");
            
            if( file.KeyExists("Trademarks", "Details"))
                info.trademarks = file.ReadValue("Trademarks", "Details");

            if( file.KeyExists("Freeware", "License"))
                info.freeware = file.ReadValue("Freeware", "License");

            if( file.KeyExists("Shareable", "License"))
                info.sharable = file.ReadValue("Shareable", "License");
            
            if( file.KeyExists("OpenSource", "License"))
                info.opensource = file.ReadValue("OpenSource", "License");
            
            if( file.KeyExists("CommercialUse", "License"))
                info.commercialuse = file.ReadValue("CommercialUse", "License");
            
            if( file.KeyExists("EULAVersion", "License"))
                info.eulaVersion = file.ReadValue("EULAVersion", "License");

            if( file.KeyExists("UsesDotNetVersion", "Dependencies"))
                info.dotnet = file.ReadValue("UsesDotNetVersion", "Dependencies");
                
            if( file.KeyExists("UsesGhostscript", "Dependencies"))
                info.ghostscript = file.ReadValue("UsesGhostscript", "Dependencies");
                
            if( file.KeyExists("UsesJava", "Dependencies"))
                info.java = file.ReadValue("UsesJava", "Dependencies");

            if( file.KeyExists("PackageVersion", "Version"))
                info.packageVersion = file.ReadValue("PackageVersion", "Version");
                
            if( file.KeyExists("DisplayVersion", "Version"))
                info.displayVersion = file.ReadValue("DisplayVersion", "Version");
                
            if( file.KeyExists("Plugins", "SpecialPaths"))
                info.pluginspath = file.ReadValue("Plugins", "SpecialPaths");
        }
        #endregion
    }

}
